<template>
  <div class="score-input-container">
    <!-- 新增：添加工具栏（包含导出按钮） 8.12-->
    <!-- 新增：展示课程、班级等信息 -->
    <div class="course-info">
      <span class="info-item"><span class="info-label">课程名称：</span>{{ courseName }}</span>
      <span class="info-item"><span class="info-label">班级名称：</span>{{ className }}</span>
      <span class="info-item"><span class="info-label">开课学期：</span>{{ semesterLabel }}</span>
      <span class="info-item"><span class="info-label">年级：</span>{{ grade }}</span>
    </div>
    <div class="score-toolbar">
      <h3>成绩录入管理</h3>
      <div class="toolbar-buttons">
        <el-button
            type="success"
            icon="Check"
            size="default"
            @click="handleBatchSubmit"
            :loading="batchSubmitLoading"
            :disabled="!hasSelectedItems"
        >
          批量提交当前页
        </el-button>
        <el-button
            type="primary"
            icon="Download"
            size="default"
            @click="handleExportAll"
            :loading="exportLoading"
            style="margin-left: 10px"
        >
          导出所有成绩
        </el-button>

        <!-- 第一步：仅负责选择文件（不自动上传） -->
        <el-upload
            class="upload-file-btn"
            action=""
            :auto-upload="false"
            :on-change="handleFileChange"
            :file-list="selectedFileList"
            accept=".xlsx"
            style="margin-left: 10px"
        >
          <el-button type="info" icon="Upload" size="default">选择Excel文件</el-button>
        </el-upload>

        <!-- 第二步：开始导入（仅在选择文件后启用） -->
        <el-button
            type="warning"
            icon="RefreshLeft"
            size="default"
            @click="handleStartImport"
            :loading="importLoading"
            :disabled="!hasSelectedFile"
            style="margin-left: 10px"
        >
          开始导入
        </el-button>

      </div>
    </div>


    <!-- 1. 成绩组成配置弹窗 -->
    <el-dialog
        title="成绩组成配置"
        v-model="dialogVisible"
        width="600px"
        @open="resetConfig"
    >
      <div class="config-content">
        <!-- 成绩项选择 -->
        <el-checkbox-group v-model="selectedItems">
          <el-checkbox
              v-for="item in scoreItems"
              :key="item.value"
              :label="item.value"
          >
            {{ item.label }}
          </el-checkbox>
        </el-checkbox-group>

        <!-- 占比输入（仅选中项显示） -->
        <div
            v-for="item in selectedScoreItems"
            :key="item.value"
            class="ratio-row"
        >
          <span>{{ item.label }} 占比：</span>
          <el-input-number
              v-model.number="ratioConfig[item.value]"
              :min="1"
              :max="99"
              controls-position="right"
              @change="calcTotalRatio"
          />
          <span class="ratio-unit">%</span>
        </div>

        <!-- 占比总和校验 -->
        <div class="ratio-total">
          当前选中项占比总和：
          <span :class="{ error: totalRatio !== 100 }">{{ totalRatio }}%</span>
          <div v-if="totalRatio !== 100" class="error-tip">
            占比总和必须为 100% 才能保存设置！
          </div>
        </div>
      </div>

      <template #footer>
        <el-button @click="dialogVisible = false">取消</el-button>
        <el-button
            type="primary"
            @click="confirmConfig"
            :disabled="totalRatio !== 100"
        >
          保存设置
        </el-button>
      </template>
    </el-dialog>

    <!-- 2. 成绩录入表格（动态列） -->
    <!-- 8.12批量提交新增：用于获取选中行 ref="multipleTable"  :row-key="row => row.studentId" -->
    <el-card class="score-table">
      <el-table
          ref="multipleTable"
          :data="tableData"
          border
          :row-class-name="getRowClassName"
          v-loading="loading"
          :row-key="row => row.studentId"
          @selection-change="handleSelectionChange"
      >
        <!-- 1. 批量提交新增：多选列 8.12-->
        <el-table-column
            type="selection"
            :selectable="row => row.status !== '已提交'"
            width="50"
        />
        <el-table-column label="序号" type="index" width="60" />
        <el-table-column label="学号" prop="studentNo" width="160" />
        <el-table-column label="学生姓名" prop="studentName" width="180" />
        <!--        新增是否缺考列-->
        <el-table-column label="是否缺考" min-width="120">
          <template #default="scope">
            <el-radio-group
                v-model="scope.row.absentExam"
                :disabled="scope.row.status === '已提交'"
                @change="() => handleAbsentChange(scope.row)"
            >
              <el-radio :label="0">否</el-radio>
              <el-radio :label="1">是</el-radio>
            </el-radio-group>
          </template>
        </el-table-column>


        <!-- 动态成绩列：根据弹窗配置渲染 -->
        <template v-for="(col, idx) in dynamicColumns" :key="idx">
          <el-table-column :label="col.label" min-width="150">
            <template #default="scope">
              <el-input-number
                  v-model="scope.row[col.field]"
                  :min="0"
                  :max="100"
                  :disabled="scope.row.status === '已提交'"
                  controls-position="right"
                  @change="() => calculateTotalAndGrade(scope.row)"
              />
            </template>
          </el-table-column>
        </template>

        <el-table-column label="总成绩" prop="totalScore" min-width="120" />
        <el-table-column label="绩点" prop="gradePoint" min-width="100" />
        <el-table-column label="状态" prop="status" min-width="120">
          <template #default="scope">
            <el-tag :type="getStatusTagType(scope.row.status)">{{ scope.row.status }}</el-tag>
          </template>
        </el-table-column>
        <el-table-column label="操作" min-width="100">
          <template #default="scope">
            <el-button
                type="primary"
                size="mini"
                @click="handleSubmit(scope.row)"
                :disabled="scope.row.status === '已提交'"
            >提交</el-button>
          </template>
        </el-table-column>
      </el-table>
    </el-card>

    <!-- 3. 分页组件 -->
    <div class="pagination-wrapper">
      <el-pagination
          @size-change="handleSizeChange"
          @current-change="handleCurrentChange"
          :current-page="currentPage"
          :page-sizes="[10, 20, 50]"
          :page-size="pageSize"
          layout="total, sizes, prev, pager, next, jumper"
          :total="total"
          style="margin-top: 20px; text-align: center;"
      />
    </div>
  </div>
</template>

<script setup>
//8.12token
import { getToken } from '@/utils/auth'
import { ref, onMounted, computed, watch } from 'vue'
import {
  ElCard, ElTable, ElTableColumn, ElInputNumber, ElTag,
  ElMessage, ElLoading, ElDialog, ElCheckboxGroup, ElCheckbox, ElButton,
  ElPagination, ElMessageBox
} from 'element-plus'
import { useRoute } from 'vue-router'



import { getEnrolledStudents, submitScore, saveScoreConfig, getScoreConfig,importScore } from '@/api/trainingManagement/details'


// 新增，在表头显示该课程的信息
const route = useRoute();
// 从路由参数中获取课程名称、班级名称、开课学期、年级
const courseName = ref(route.query.courseName || '');
const className = ref(route.query.className || '');
const semester = ref(route.query.semester || '');
const grade = ref(route.query.grade || '');
// 获取学期字典，和课程排课详细信息页使用的是同一个字典
// 存储后端返回的学期字典数据
// 手动建立学期映射关系
const semesterMap = {
  '1': '秋季第一学期',
  '2': '春季第二学期',
  '3': '寒假第一学期',
  '4': '暑假第二学期'
};

// 计算展示的学期标签
const semesterLabel = computed(() => {
  const key = String(semester.value);
  return semesterMap[key] || `未知学期(${key})`;
});


// 新增：导入相关状态（分步控制核心）
const selectedFileList = ref([]); // 暂存已选择的文件列表
const currentFile = ref(null);    // 存储当前选中的文件（单个文件导入）
const importLoading = ref(false); // 导入加载状态

// 计算属性：是否有已选择的文件（控制“开始导入”按钮禁用）
const hasSelectedFile = computed(() => {
  return currentFile.value !== null;
});

/**
 * 第一步：文件选择变化时触发（暂存文件，不发请求）
 * @param file 选中的文件
 * @param fileList 已选文件列表
 */
const handleFileChange = (file, fileList) => {
  console.log('==== 前端：选择文件触发 ====');
  // 1. 校验文件格式（xlsx）
  const isXLSX = file.raw.type === 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
      || file.raw.name.endsWith('.xlsx');
  if (!isXLSX) {
    ElMessage.error('请选择.xlsx格式的Excel文件！');
    selectedFileList.value = []; // 清空无效文件
    currentFile.value = null;
    console.error('文件格式错误，已清空选择：', file.raw.name);
    return;
  }

  // 2. 校验文件大小（≤5MB）
  const isLt5M = file.raw.size / 1024 / 1024 <= 5;
  if (!isLt5M) {
    ElMessage.error('Excel文件大小不能超过5MB！');
    selectedFileList.value = []; // 清空过大文件
    currentFile.value = null;
    console.error('文件过大，已清空选择：', file.raw.name, '大小：', (file.raw.size/1024/1024).toFixed(2) + 'MB');
    return;
  }

  // 3. 暂存文件（仅保留最新选择的1个文件）
  selectedFileList.value = [file]; // 覆盖旧文件
  currentFile.value = file.raw; // 存储原始文件对象
  console.log('文件选择成功，暂存文件信息：', {
    fileName: currentFile.value.name,
    fileSize: (currentFile.value.size/1024/1024).toFixed(2) + 'MB',
    fileType: currentFile.value.type
  });
  ElMessage.success(`已选择文件：${currentFile.value.name}`);
};

/**
 * 第二步：点击“开始导入”触发（发送请求到后端）
 */
const handleStartImport = async () => {
  console.log('==== 前端：点击“开始导入”触发 ====');
  // 1. 基础校验（防止异常情况）
  if (!currentFile.value) {
    ElMessage.warning('请先选择Excel文件！');
    console.error('未选择文件，终止导入');
    return;
  }
  if (!courseScheduleDetailsId) {
    ElMessage.warning('未获取到课程班信息，无法导入！');
    console.error('courseScheduleDetailsId为空，终止导入');
    return;
  }

  // 2. 二次确认（避免误操作）
  try {
    await ElMessageBox.confirm(
        `确定要导入文件【${currentFile.value.name}】吗？导入后将覆盖现有成绩（如有）`,
        '确认导入',
        { confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning' }
    );
  } catch (error) {
    ElMessage.info('已取消导入');
    console.log('用户取消导入操作');
    return;
  }

  // 3. 构造FormData（准备发送请求）
  const formData = new FormData();
  formData.append('file', currentFile.value); // 后端@RequestParam("file")
  formData.append('courseScheduleDetailsId', courseScheduleDetailsId); // 后端@RequestParam("courseScheduleDetailsId")
  console.log('构造请求FormData：', {
    courseScheduleDetailsId: courseScheduleDetailsId,
    fileName: currentFile.value.name
  });
  // 打印FormData内容（遍历查看，FormData无法直接console.log）
  console.log('FormData详细内容：');
  for (const [key, value] of formData.entries()) {
    console.log(`${key}: ${key === 'file' ? value.name : value}`);
  }

  // 4. 发送导入请求
  importLoading.value = true;
  try {
    console.log('开始调用后端importScore接口');
    const res = await importScore(formData);
    // 5. 处理成功响应
    console.log('后端导入接口响应成功：', res);
    const { successCount, failCount, failReasons } = res.data;
    ElMessage.success(`导入完成！成功${successCount}条，失败${failCount}条`);

    // 显示失败详情（如有）
    if (failCount > 0) {
      await ElMessageBox.alert(
          `失败详情：\n${failReasons.join('\n')}`,
          '导入结果',
          { type: 'error', dangerouslyUseHTMLString: true }
      );
    }

    // 6. 刷新表格（展示导入后的成绩）
    await getList();
    console.log('导入后刷新表格数据成功');

    // 7. 重置选择（导入完成后清空文件）
    selectedFileList.value = [];
    currentFile.value = null;
  } catch (error) {
    // 8. 处理失败响应
    console.error('后端导入接口调用失败：', error);
    ElMessage.error(`导入失败：${error.message || '服务器异常'}`);
  } finally {
    importLoading.value = false;
    console.log('==== 前端：导入流程结束 ====');
  }
};



// 基础状态
// const route = useRoute()
const courseScheduleDetailsId = route.query.courseScheduleDetailsId
const tableData = ref([])
const loading = ref(false)

// =======8.12导出
const exportLoading = ref(false)

// 8.12批量提交
const batchSubmitLoading = ref(false)
const multipleTable = ref(null);
const selectedRows = ref([]); // 存储选中行

// 监听选择变化
const handleSelectionChange = (rows) => {
  selectedRows.value = rows;
};

// 判断是否有选中项
const hasSelectedItems = computed(() => {
  return selectedRows.value.length > 0;
});

// 分页逻辑
const rawData = ref([]);
const currentPage = ref(1);
const pageSize = ref(10);
const total = ref(0);

const updateTableData = () => {
  const start = (currentPage.value - 1) * pageSize.value;
  const end = start + pageSize.value;
  tableData.value = rawData.value.slice(start, end);
};

// 成绩配置弹窗逻辑
const dialogVisible = ref(false)
const scoreItems = ref([
  { value: 'regular', label: '平时成绩', field: 'regularScore', dbField: 'attendanceScore' },
  { value: 'final', label: '期末成绩', field: 'finalScore', dbField: 'examScore' },
  { value: 'experiment', label: '实验成绩', field: 'experimentScore', dbField: 'experimentScore' },
  { value: 'midterm', label: '期中成绩', field: 'midtermScore', dbField: 'midtermScore' },
  { value: 'courseDesign', label: '课程设计成绩', field: 'courseDesignScore', dbField: 'courseDesignScore' },
  { value: 'other', label: '其他成绩', field: 'otherScore', dbField: 'otherScore' },
])
const selectedItems = ref([])
const ratioConfig = ref({})
const totalRatio = ref(0)
const dynamicColumns = ref([])
const scoreConfig = ref([])

const selectedScoreItems = computed(() => {
  return scoreItems.value.filter(item => selectedItems.value.includes(item.value))
})

const resetConfig = () => {
  selectedItems.value = []
  ratioConfig.value = {}
  totalRatio.value = 0
}

const calcTotalRatio = () => {
  totalRatio.value = selectedItems.value.reduce((sum, item) => sum + (ratioConfig.value[item] || 0), 0)
}

const confirmConfig = async () => {
  // 保存配置到后端
  const config = selectedScoreItems.value.map(item => ({
    field: item.field,
    dbField: item.dbField,
    ratio: ratioConfig.value[item.value]
  }))
  scoreConfig.value = config
  dynamicColumns.value = config.map(item => ({
    label: scoreItems.value.find(i => i.field === item.field).label,
    field: item.field
  }))

  await saveScoreConfig({
    courseId: courseScheduleDetailsId,
    config: JSON.stringify(config)
  })
  dialogVisible.value = false
}

// 数据加载
const getList = async () => {
  if (!courseScheduleDetailsId) return
  loading.value = true
  try {
    const res = await getEnrolledStudents(courseScheduleDetailsId)
    rawData.value = res.data.map(row => {
      // 初始化所有成绩字段为0
      scoreItems.value.forEach(item => {
        if (row[item.field] === undefined) row[item.field] = 0
      })
      // ==========8.14新增：初始化是否缺考（默认0=否）
      // 关键：强制转换为数字，避免字符串类型问题
      row.absentExam = Number(row.absentExam);
      if (row.absentExam === undefined || row.absentExam === null) {
        row.absentExam = 0;
      }
      return row
    })
    total.value = rawData.value.length
    updateTableData()
  } catch (error) {
    ElMessage.error(`加载失败：${error.message}`)
  } finally {
    loading.value = false
  }
};

// 初始化：获取配置+加载数据
onMounted(async () => {
  if (!courseScheduleDetailsId) return
  try {
    const res = await getScoreConfig(courseScheduleDetailsId)
    if (res.data) {
      scoreConfig.value = res.data
      dynamicColumns.value = res.data.map(item => ({
        label: scoreItems.value.find(i => i.field === item.field).label,
        field: item.field
      }))
    } else {
      dialogVisible.value = true
    }
  } catch (error) {
    ElMessage.warning('未找到配置，请重新设置')
    dialogVisible.value = true
  }
  await getList()
})

// 成绩计算
const calculateTotalAndGrade = (row) => {
  let totalScore = 0
  scoreConfig.value.forEach(({ field, ratio }) => {
    totalScore += (row[field] || 0) * (ratio / 100)
  })
  row.totalScore = Number(totalScore.toFixed(2))

  // 绩点计算
  if (totalScore >= 90) row.gradePoint = 4.0
  else if (totalScore >= 80) row.gradePoint = 3.0
  else if (totalScore >= 70) row.gradePoint = 2.0
  else if (totalScore >= 60) row.gradePoint = 1.0
  else row.gradePoint = 0.0
}

// 提交单行成绩
const handleSubmit = async (row) => {
  if (row.status === '已提交') return
  const submitData = {
    studentId: row.studentId,
    courseScheduleDetailsId: courseScheduleDetailsId,
    totalScore: row.totalScore,
    gradePoint: row.gradePoint,
    isPassed: row.totalScore >= 60 ? 1 : 0,
    absentExam: row.absentExam  // 新增：是否缺考
  }

  scoreConfig.value.forEach(({ field, dbField }) => {
    submitData[dbField] = row[field]
  })

  try {
    await submitScore(submitData)
    ElMessage.success('提交成功')
    await getList()
  } catch (error) {
    ElMessage.error(`提交失败：${error.message}`)
  }
}

// 批量提交
const handleBatchSubmit = async () => {
  if (selectedRows.value.length === 0) {
    ElMessage.info('请选择要提交的成绩记录');
    return;
  }

  try {
    await ElMessageBox.confirm(
        `确定要提交选中的 ${selectedRows.value.length} 条成绩吗？`,
        '确认提交',
        { confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning' }
    );

    batchSubmitLoading.value = true;
    let successCount = 0, failCount = 0;
    const errorMessages = [];

    // 遍历选中行提交
    for (const row of selectedRows.value) {
      try {
        const submitData = {
          studentId: row.studentId,
          courseScheduleDetailsId: courseScheduleDetailsId,
          totalScore: row.totalScore,
          gradePoint: row.gradePoint,
          isPassed: row.totalScore >= 60 ? 1 : 0,
          absentExam: row.absentExam  // 新增：是否缺考
        };

        scoreConfig.value.forEach(({ field, dbField }) => {
          submitData[dbField] = row[field];
        });

        await submitScore(submitData);
        successCount++;
      } catch (error) {
        failCount++;
        errorMessages.push(`学生 ${row.studentName} (${row.studentNo}): ${error.message}`);
      }
    }

    // 刷新数据 + 清空选中
    await getList();
    multipleTable.value.clearSelection();

    // 结果提示
    if (successCount > 0) {
      ElMessage.success(`批量提交完成：成功 ${successCount} 条，失败 ${failCount} 条`);
    }
    if (failCount > 0) {
      ElMessageBox.alert(
          `部分提交失败：\n${errorMessages.join('\n')}`,
          '提交结果',
          { type: 'error' }
      );
    }
  } catch (error) {
    if (error === 'cancel') return;
    ElMessage.error(`批量提交失败：${error.message || '未知错误'}`);
  } finally {
    batchSubmitLoading.value = false;
  }
};

// 导出所有成绩
const handleExportAll = async () => {
  if (!courseScheduleDetailsId) {
    ElMessage.warning('未获取到课程信息，无法导出')
    return
  }

  if (rawData.value.length === 0) {
    ElMessage.info('没有可导出的成绩数据')
    return
  }

  exportLoading.value = true
  try {
    const url = `${import.meta.env.VITE_APP_BASE_API}/training/grade-input/export-all/${courseScheduleDetailsId}`
    const response = await fetch(url, {
      method: 'GET',
      headers: {
        'Authorization': `Bearer ${getToken()}`,
        'Content-Type': 'application/json'
      }
    })

    if (!response.ok) throw new Error('导出失败，请重试')

    // 处理文件下载
    const blob = await response.blob()
    const contentDisposition = response.headers.get('content-disposition')
    let fileName = '学生成绩表.xlsx'

    if (contentDisposition && contentDisposition.includes('filename=')) {
      fileName = decodeURIComponent(
          contentDisposition.split('filename=')[1].replace(/"/g, '')
      )
    }

    // 创建下载链接
    const urlObject = URL.createObjectURL(blob)
    const a = document.createElement('a')
    a.href = urlObject
    a.download = fileName
    document.body.appendChild(a)
    a.click()

    // 清理资源
    document.body.removeChild(a)
    URL.revokeObjectURL(urlObject)
    ElMessage.success('导出成功')
  } catch (error) {
    ElMessage.error(`导出失败：${error.message}`)
  } finally {
    exportLoading.value = false
  }
}

// 辅助方法
const getStatusTagType = (status) => status === '已提交' ? 'success' : 'warning'
const getRowClassName = (row) => row.status === '已提交' ? 'disabled-row' : ''
const handleSizeChange = (val) => { pageSize.value = val; updateTableData() }
const handleCurrentChange = (val) => { currentPage.value = val; updateTableData() }

watch(selectedItems, () => {
  selectedItems.value.forEach(item => {
    if (ratioConfig.value[item] === undefined) ratioConfig.value[item] = 0
  })
  calcTotalRatio()
})
watch(ratioConfig, calcTotalRatio, { deep: true })




</script>

<style scoped>
.config-content { padding: 16px; }
.ratio-row { display: flex; align-items: center; margin: 12px 0; }
.ratio-row span { margin-right: 8px; }
.ratio-unit { margin-left: 4px; }
.ratio-total { margin-top: 16px; color: #666; }
.error { color: #ff4d4f; }
.error-tip { color: #ff4d4f; font-size: 12px; margin-top: 4px; }
.pagination-wrapper {
  display: flex;
  justify-content: center;
  width: 100%;
}

.score-toolbar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 16px;
  padding: 0 16px;
}

.score-toolbar h3 {
  margin: 0;
  font-size: 16px;
  font-weight: 600;
}

.score-table {
  margin-bottom: 16px;
}

.toolbar-buttons {
  display: flex;
  align-items: center;
}

:deep(.disabled-row) {
  background-color: #f5f7fa;
}


/* 新增：调整文件选择按钮样式，与开始导入按钮对齐 */
.upload-file-btn .el-upload--button {
  display: inline-block;
}

.course-info {
  margin-bottom: 16px;
  padding: 10px;
  background-color: #f9fafc;
  border-radius: 4px;
}
.info-label {
  font-weight: bold;
  margin-right: 5px;
}
.course-info {
  display: flex;
  flex-wrap: wrap;
  gap: 20px;
  margin-bottom: 16px;
  padding: 10px;
  background-color: #f9fafc;
  border-radius: 4px;
}
.info-item {
  display: flex;
  align-items: center;
}
.info-label {
  font-weight: bold;
  margin-right: 5px;
}
.config-content { padding: 16px; }
.ratio-row { display: flex; align-items: center; margin: 12px 0; }
.ratio-row span { margin-right: 8px; }
.ratio-unit { margin-left: 4px; }
.ratio-total { margin-top: 16px; color: #666; }
.error { color: #ff4d4f; }
.error-tip { color: #ff4d4f; font-size: 12px; margin-top: 4px; }
.pagination-wrapper {
  display: flex;
  justify-content: center;
  width: 100%;
}

.score-toolbar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 16px;
  padding: 0 16px;
}

.score-toolbar h3 {
  margin: 0;
  font-size: 16px;
  font-weight: 600;
}

.score-table {
  margin-bottom: 16px;
}

.toolbar-buttons {
  display: flex;
  align-items: center;
}

:deep(.disabled-row) {
  background-color: #f5f7fa;
}


/* 新增：调整文件选择按钮样式，与开始导入按钮对齐 */
.upload-file-btn .el-upload--button {
  display: inline-block;
}

.course-info {
  margin-bottom: 16px;
  padding: 15px;
  background-color: #e6f7ff;
  border: 1px solid #91d5ff;
  border-radius: 6px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}
.info-item {
  margin-right: 20px;
  font-size: 14px;
}
.info-label {
  font-weight: bold;
  color: #1890ff;
  margin-right: 5px;
}
/* 调整“选择Excel文件”按钮与相邻按钮高度一致 */
.upload-file-btn .el-upload {
  display: inline-block;
  vertical-align: middle; /* 与相邻按钮垂直对齐 */
}
.upload-file-btn .el-button {
  height: 32px;         /* 与Element Plus默认按钮高度一致 */
  line-height: 32px;    /* 文字垂直居中 */
  display: inline-flex; /* 保证图标与文字对齐 */
  align-items: center;  /* 图标与文字垂直居中 */
}
</style>